package com.jgc.blockingqueue;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * DelayQueue是基于优先级的一个无界队列，队列元素必须实现Delayed接口，
 * 支持延迟获取，元素按照时间排序，只有元素到期后，消费者才能从队列中取出。
 * DelayQueue属于排序队列，它的特殊之处在于队列的元素必须实现Delayed接口，该接口需要实现compareTo和getDelay方法。
 */
public class DelayQueueTest {
    public static void main(String[] args) throws InterruptedException {
        DelayQueue<DelayedElement> delayeds = new DelayQueue<>();
        delayeds.put(new DelayedElement(3000,"task1"));
        delayeds.put(new DelayedElement(1000,"task2"));
        delayeds.put(new DelayedElement(5000,"task3"));
        delayeds.put(new DelayedElement(7000,"task4"));
        for (int i = 0; i < 4; i++) {
            DelayedElement take = delayeds.take();
            System.out.println("element taken:" + take.taskId);
        }
    }
 static  class DelayedElement implements Delayed {
        private long delayTime;
        private long expire;

        private String taskId;

        public DelayedElement(long delayTime,String taskId) {
            this.delayTime = delayTime;
            this.expire = System.currentTimeMillis() + delayTime;
            this.taskId = taskId;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            return Long.compare(this.expire, ((DelayedElement) o).expire);
        }
    }
}